using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using UniversalAdmin.Api.Models;
using UniversalAdmin.Application.Common;
using UniversalAdmin.Application.DTOs;
using UniversalAdmin.Application.Features.Users.Queries;
using UniversalAdmin.Application.Services;
using UniversalAdmin.Domain.Interfaces;

namespace UniversalAdmin.Api.Controllers;

/// <summary>
/// 用户管理控制器 - 示例受保护的API
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize] // 要求认证
public class UsersController : ControllerBase
{
    private readonly IUnitOfWork _unitOfWork;
    private readonly IUserService _userService;
    private readonly IPasswordHasher _passwordHasher;
    private readonly IAuthService _authService;

    public UsersController(IUnitOfWork unitOfWork, IUserService userService,
        IPasswordHasher passwordHasher,
        IAuthService authService)
    {
        _unitOfWork = unitOfWork;
        _userService = userService;
        _passwordHasher = passwordHasher;
        _authService = authService;
    }

    /// <summary>
    /// 获取当前用户信息 - 任何认证用户都可以访问
    /// </summary>
    [HttpGet("me")]
    public async Task<IActionResult> GetCurrentUser()
    {
        var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (userIdClaim == null || !int.TryParse(userIdClaim, out var userId))
            return Unauthorized();

        var user = await _unitOfWork.UserRepository.GetUserWithRolesAsync(userId);
        if (user == null)
            return NotFound();

        var result = new
        {
            user.Id,
            user.Username,
            user.Email,
            user.Phone,
            user.Avatar,
            user.IsActive,
            Roles = user.UserRoles?.Select(ur => ur.Role?.Name).Where(name => name != null) ?? new List<string>()
        };

        return Ok(result);
    }

    // 把“查看单个用户”升级为“带菜单”
    [HttpGet("{id:int}/detail")]
    [Authorize(Roles = "Admin,SuperAdmin")]
    public async Task<IActionResult> GetUserDetail(int id)
    {
        var dto = await _userService.GetUserWithMenusAsync(id);
        return Ok(ApiResponse<UserWithMenusDto>.Success(dto));
    }

    /// <summary>
    /// 获取指定用户信息 - 只能查看自己的信息，除非是管理员
    /// </summary>
    [HttpGet("{id:int}")]
    [Authorize("user.view")]
    public async Task<IActionResult> GetUser(int id)
    {
        var user = await _userService.GetUserByIdAsync(id);
        if (user == null) return NotFound(ApiResponse.Error(404, "用户不存在"));

        // 普通用户只能看自己的信息
        var currentUserId = GetCurrentUserId();
        var roles = await _authService.GetUserRolesAsync(currentUserId);
        var isAdmin = roles.Contains("Admin") || roles.Contains("SuperAdmin");
        if (!isAdmin && currentUserId != id)
            return Forbid("您只能查看自己的信息");

        return Ok(ApiResponse<UserDto>.Success(user));
    }

    [HttpGet("search")]
    public async Task<ActionResult<ApiResponse<PagedResult<UserDto>>>> Search(
        [FromQuery] string? userName,
        [FromQuery] string? email,
        [FromQuery] int page = 1,
        [FromQuery] int size = 10)
    {
        var result = await _userService.SearchUsersAsync(userName, email, page, size);
        return Ok(ApiResponse<PagedResult<UserDto>>.Success(result, "查询成功"));
    }

    /// <summary>
    /// 更新当前登录用户个人信息
    /// </summary>
    [HttpPut("profile")]
    public async Task<IActionResult> UpdateProfile([FromBody] UpdateProfileDto dto)
    {
        if (!ModelState.IsValid)
        {
            var errors = ModelState
                .Where(x => x.Value?.Errors?.Count > 0)
                .Select(x => new { Field = x.Key, Errors = x.Value?.Errors?.Select(e => e.ErrorMessage) ?? Enumerable.Empty<string>() })
                .ToList();
            
            return BadRequest(new 
            { 
                type = "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                title = "One or more validation errors occurred.",
                status = 400,
                errors = errors.ToDictionary(x => x.Field, x => x.Errors.ToArray()),
                traceId = HttpContext.TraceIdentifier
            });
        }

        var userId = GetCurrentUserId();
        var user = await _unitOfWork.UserRepository.GetByIdAsync(userId);
        if (user == null) return NotFound(ApiResponse.Error(404, "用户不存在"));

        // 邮箱唯一性校验（排除自己）
        if (await _unitOfWork.UserRepository.IsEmailExistsAsync(dto.Email, userId))
            return BadRequest(ApiResponse.Error(400, "邮箱已存在"));

        user.Email = dto.Email;
        user.Phone = dto.Phone;
        if (!string.IsNullOrEmpty(dto.Avatar))
        {
            user.Avatar = dto.Avatar;
        }
        user.UpdatedAt = DateTime.UtcNow;

        await _unitOfWork.UserRepository.UpdateAsync(user);
        await _unitOfWork.SaveChangesAsync();

        return Ok(ApiResponse.Success("个人信息更新成功"));
    }

    /// <summary>
    /// 修改登录用户密码
    /// </summary>
    [HttpPut("change-password")]
    public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordDto dto)
    {
        if (!ModelState.IsValid)
            return BadRequest(ApiResponse.Error(400, "参数验证失败"));

        var userId = GetCurrentUserId();
        var user = await _unitOfWork.UserRepository.GetByIdAsync(userId);
        if (user == null) return NotFound(ApiResponse.Error(404, "用户不存在"));

        if (!_passwordHasher.Verify(dto.OldPassword, user.Password))
            return BadRequest(ApiResponse.Error(400, "原密码错误"));

        user.Password = _passwordHasher.Hash(dto.NewPassword);
        user.UpdatedAt = DateTime.UtcNow;

        await _unitOfWork.UserRepository.UpdateAsync(user);
        await _unitOfWork.SaveChangesAsync();

        return Ok(ApiResponse.Success("密码修改成功"));
    }



    private int GetCurrentUserId()
    {
        var idClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        return int.TryParse(idClaim, out var id) ? id : throw new UnauthorizedAccessException("无法获取当前用户");
    }

    /// <summary>
    /// 获取用户列表（分页 + 关键字）
    /// </summary>
    [HttpGet]
    [Authorize("user.view")]
    public async Task<IActionResult> GetUsers(
        [FromQuery] string? keyword = null,
        [FromQuery] bool? isActive = null,
        [FromQuery] int page = 1,
        [FromQuery] int size = 10)
    {
        var result = await _userService.GetUsersAsync(new UserQueryParameters
        {
            Keyword = keyword,
            IsActive = isActive,
            PageIndex = page,
            PageSize = size
        });

        return Ok(ApiResponse<PagedResult<UserDto>>.Success(result));
    }

    /// <summary>
    /// 创建用户
    /// </summary>
    [HttpPost]
    [Authorize("user.create")]
    public async Task<IActionResult> CreateUser([FromBody] CreateUserDto dto)
    {
        if (!ModelState.IsValid)
            return BadRequest(ApiResponse.Error(400, "参数验证失败"));

        var created = await _userService.CreateUserAsync(dto);
        return CreatedAtAction(nameof(GetUser), new { id = created.Id },
            ApiResponse<UserDto>.Success(created, "用户创建成功"));
    }

    /// <summary>
    /// 更新用户（管理员）
    /// </summary>
    [HttpPut("{id:int}")]
    [Authorize("user.update")]
    public async Task<IActionResult> UpdateUser(int id, [FromBody] UpdateUserDto dto)
    {
        if (!ModelState.IsValid)
            return BadRequest(ApiResponse.Error(400, "参数验证失败"));

        // 超级管理员可改所有人，管理员不能改超级管理员
        var currentUserId = GetCurrentUserId();
        var roles = await _authService.GetUserRolesAsync(currentUserId);
        var isSuperAdmin = roles.Contains("SuperAdmin");

        var targetUser = await _unitOfWork.UserRepository.GetUserWithRolesAsync(id);
        if (targetUser == null) return NotFound(ApiResponse.Error(404, "用户不存在"));

        var isTargetSuperAdmin = targetUser.UserRoles?.Any(ur => ur.Role?.Name == "SuperAdmin") == true;
        if (isTargetSuperAdmin && !isSuperAdmin)
            return Forbid("您无权修改超级管理员信息");

        await _userService.UpdateUserAsync(id, dto);
        return Ok(ApiResponse.Success("更新成功"));
    }

    [HttpPut("{id:int}/roles")]
    [Authorize(Roles = "SuperAdmin")]
    public async Task<IActionResult> AssignRoles(int id, [FromBody] List<int> roleIds)
    {
        await _userService.AssignRolesAsync(id, roleIds);
        return Ok(ApiResponse.Success("角色已更新"));
    }

    /// <summary>
    /// 删除用户
    /// </summary>
    [HttpDelete("{id:int}")]
    [Authorize("user.delete")]
    public async Task<IActionResult> DeleteUser(int id)
    {
        var currentUserId = GetCurrentUserId();
        if (id == currentUserId)
            return BadRequest(ApiResponse.Error(400, "不能删除自己"));

        var roles = await _authService.GetUserRolesAsync(currentUserId);
        var isSuperAdmin = roles.Contains("SuperAdmin");

        var targetUser = await _unitOfWork.UserRepository.GetUserWithRolesAsync(id);
        if (targetUser == null) return NotFound(ApiResponse.Error(404, "用户不存在"));

        var isTargetSuperAdmin = targetUser.UserRoles?.Any(ur => ur.Role?.Name == "SuperAdmin") == true;
        if (isTargetSuperAdmin && !isSuperAdmin)
            return Forbid("您无权删除超级管理员");

        await _userService.DeleteUserAsync(id);
        return Ok(ApiResponse.Success("删除成功"));
    }

    /// <summary>
    /// 管理员重置用户密码
    /// </summary>
    [HttpPut("{id:int}/reset-password")]
    [Authorize("user.update")]
    public async Task<IActionResult> ResetPassword(int id, [FromBody] ResetPasswordDto dto)
    {
        if (string.IsNullOrWhiteSpace(dto.NewPassword))
            return BadRequest(ApiResponse.Error(400, "新密码不能为空"));

        var user = await _unitOfWork.UserRepository.GetByIdAsync(id);
        if (user == null) return NotFound(ApiResponse.Error(404, "用户不存在"));

        var currentUserId = GetCurrentUserId();
        var roles = await _authService.GetUserRolesAsync(currentUserId);
        var isSuperAdmin = roles.Contains("SuperAdmin");

        var targetUser = await _unitOfWork.UserRepository.GetUserWithRolesAsync(id);
        if (targetUser == null) return NotFound(ApiResponse.Error(404, "用户不存在"));

        var isTargetSuperAdmin = targetUser.UserRoles?.Any(ur => ur.Role?.Name == "SuperAdmin") == true;
        if (isTargetSuperAdmin && !isSuperAdmin)

            return Forbid("您无权修改超级管理员信息");
        user.Password = _passwordHasher.Hash(dto.NewPassword);
        user.UpdatedAt = DateTime.UtcNow;

        await _unitOfWork.UserRepository.UpdateAsync(user);
        await _unitOfWork.SaveChangesAsync();

        return Ok(ApiResponse.Success("密码重置成功"));
    }

    ///<summary>
    /// 用户重置密码
    ///</summary>
    [HttpPut("reset-password-self")]
    [AllowAnonymous]
    public async Task<IActionResult> ResetPasswordSelf([FromBody] ResetPasswordSelfDto dto)
    {
        var user = await _unitOfWork.UserRepository.GetByUsernameAsync(dto.UserName);

        if (user == null || user.Email != dto.Email)
            return BadRequest(ApiResponse.Error(400, "用户名或邮箱无效"));

        if (string.IsNullOrWhiteSpace(dto.NewPassword))
            return BadRequest(ApiResponse.Error(400, "新密码不能为空"));

        user.Password = _passwordHasher.Hash(dto.NewPassword);
        user.UpdatedAt = DateTime.UtcNow;

        await _unitOfWork.UserRepository.UpdateAsync(user);
        await _unitOfWork.SaveChangesAsync();

        return Ok(ApiResponse.Success("密码重置成功"));
    }

}
